from django.http import HttpResponse, Http404
from django.template import loader
from django.core.paginator import Paginator
from blog.models import BlogPost, Tag, BlogCategory, Social
from django.shortcuts import render
from django.db.models import Count
from django.db.models.functions import TruncYear

import markdown2


# 首页/列表页视图实现.
def index(request):
    category_id = request.GET.get('category')
    tag_id = int(request.GET.get('tag', 0))
    year = request.GET.get('year')
    search = request.GET.get('search')
    if category_id:
        blogpost_list = BlogPost.objects.filter(category=category_id, isShow=True).order_by('-isTop', '-pubTime')
    elif tag_id:
        blogpost_list = BlogPost.objects.filter(tags__id=tag_id, isShow=True).order_by('-isTop', '-pubTime')
    elif year:
        blogpost_list = BlogPost.objects.filter(pubTime__year=year, isShow=True).order_by('-isTop', '-pubTime')
    elif search:
        blogpost_list = BlogPost.objects.filter(content__icontains=search, isShow=True).order_by('-isTop', '-pubTime')
    else:
        # 筛选出需要显示的博客文章
        blogpost_list = BlogPost.objects.filter(isShow=True).order_by('-isTop', '-pubTime', '-update_time')
    # 每页显示的数量
    per_page = 10

    # 创建分页器实例
    paginator = Paginator(blogpost_list, per_page)

    # 获取当前页码，如果没有提供，则默认为第一页
    page_number = request.GET.get('page') or 1

    # 获取当前页的数据
    page_obj = paginator.get_page(page_number)

    # 计算显示的页码范围
    current_page = int(page_number)
    pages_to_show = 11  # 当前页前后各5页加上当前页共11页
    start_page = max(current_page - 5, 1)
    end_page = min(start_page + pages_to_show - 1, paginator.num_pages)

    template = loader.get_template("blog/index.html")
    context = {
        "page_obj": page_obj,
        'start_page': start_page,
        'end_page': end_page,
        'hot_posts': get_hot_posts(),
        'tags': get_all_tags(),
        'post_grouped_by_year': get_post_groped_by_year(),
        'categories': get_categories(),
        'category_id': category_id,
        'tag_id': tag_id,
        'year': year,
        'search': search,
        'social_infos': get_socialinfo()
    }
    return HttpResponse(template.render(context, request))


# 详情页视图实现.
def post_detail(request, id):
    try:
        post_obj = BlogPost.objects.get(id=id)
        html_content = markdown2.markdown(post_obj.content,
                                          extras=["code-color", "fenced-code-blocks", "cuddled-lists", "tables",
                                                  "with-toc", "code-friendly"])
        html_content = html_content.replace('<table>', '<table class="table table-bordered">')
        html_content = html_content.replace('<img src=', '<img style="max-width:100%;height:auto;" src=')
        context = {"post_obj": post_obj,
                   "html_content": html_content,
                   "hot_posts": get_hot_posts(),
                   "tags": get_all_tags(),
                   "post_grouped_by_year": get_post_groped_by_year(),
                   'categories': get_categories(),
                   'social_infos': get_socialinfo()}
    except BlogPost.DoesNotExist:
        raise Http404("Post does not exist")
    return render(request, "blog/post.html", context)


# 关于我页视图实现.
def about(request):
    context = {'categories': get_categories(), 'social_infos': get_socialinfo()}
    return render(request, "blog/about.html", context)


def get_hot_posts():
    # 获取点赞数最高的前5篇文章
    hot_posts = BlogPost.objects.filter(isShow=True).order_by('-viewsCount', '-pubTime')[:5]
    return hot_posts


def get_all_tags():
    # 获取所有的标签
    tags = Tag.objects.all()  # 获取所有的标签
    return tags


def get_post_groped_by_year():
    # 将发布日期截断为年份，并计算每年的文章数量。
    post_grouped_by_year = (
        BlogPost.objects
        .annotate(year=TruncYear('pubTime'))
        .values('year')  # 返回的字典包含'year'键
        .annotate(publication_count=Count('id'))  # 计算每年的文章数量
        .order_by('-year')  # 按年排序
    )
    return post_grouped_by_year


def get_categories():
    # 获取所有分类
    categories = BlogCategory.objects.all()
    return categories


def get_socialinfo():
    # 获取社交信息
    social_info = Social.objects.all()
    return social_info
